﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Threading.Tasks;
using System.Data;
using System.Collections.Specialized;
using static RAP.Framework.Libary.DataSource.ServiceUtils;
using RAP.Framework.Libary.Utils;
using RAP.Framework.Libary.SqlTaskParser;
using RAP.Framework.Libary.DataSource.Model;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;
using RAP.Framework.Libary.DataSource.Context;
using RAP.Framework.Libary.Utils.Collections.Limited;
using RAP.Framework.Libary.DataSource.Model.DataSource;

namespace RAP.Framework.Libary.DataSource.Service
{
  /// <summary>
  /// 数据查询服务基类
  /// </summary>
  public class ServiceBase : IDataSourceService
  {
    /// <summary>
    /// 服务日志队列，只记录有限的最近几条
    /// </summary>
    /// public static LimitedQueue<ServiceLog> LogsQueue = new LimitedQueue<ServiceLog>(100);

    /// <summary>
    /// 
    /// </summary>
    public DataSourceConfig DataConfigration { get; set; }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="param"></param>
    /// <param name="result"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public virtual async Task<bool> InvokeService(IQueryParams param, IQueryResult result, IDataServiceContext context = null)
    {
      return await Task.FromResult(false);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="param"></param>
    /// <param name="result"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public virtual bool InvokeServiceSync(IQueryParams param, IQueryResult result, IDataServiceContext context = null)
    {
      return false;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="task"></param>
    /// <param name="param"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public virtual int RunServiceTask(SqlTask task, IQueryParams param, IDataServiceContext context)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 解析IDataReader的数据
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="parseContext">解析时用到的上下文对象</param>
    /// <param name="totalDataCount"></param>
    /// <param name="defaultDataType">默认的结果集类型</param>
    /// <param name="resultAlias"></param>
    /// <returns></returns>
    public virtual IDictionary ParseData(
        IDataReader reader,
        DataParseContext parseContext,
        out int totalDataCount,
        string defaultDataType = DataResultTypes.Dictionary,
        IList<string> resultAlias = null,
        IDictionary resultObject = null)
    {
      if (resultObject == null)
      {
        resultObject = new ListDictionary();
      }
      var resultIndex = 0;
      totalDataCount = 0;

      do
      {
        //分析结果集的别名和后取字段
        var alias = resultIndex.ToString();
        var resultDataType = defaultDataType;//默认返回键值对
        IList pickFields = null;
        if (resultAlias != null && resultIndex < resultAlias.Count)
        {
          alias = resultAlias[resultIndex];
          resultDataType = alias.PickSubstring('(', ')', out alias).IsNullOrEmptyValue(resultDataType).Trim();
          if (resultDataType.IndexOf(',') > 0)
          {
            parseContext.ModelParams = resultDataType.LeftEndString(',').Trim();
            resultDataType = resultDataType.LeftSubstring(',').Trim();
          }
          var fields = alias.PickSubstring('[', ']', out alias).Trim();
          if (fields.IsNotNullOrEmpty())
          {
            pickFields = fields.Split(',');//获取后取字段集合，如果该集合存在，则只读取第一条记录的指定字段
          }
        }
        //根据已定义的数据解析器来解析数据
        var parser = DataSourceHelper.DataReaderParsers[resultDataType];
        var parserResult = parser.ParseData(reader, pickFields, resultDataType, parseContext);
        if (pickFields.IsNotNullOrEmpty())
        {
          var firstField = pickFields.First<string>();
          if (pickFields.Count == 1 && firstField != "*")
          {
            resultObject[alias] = parserResult.DataValue.GetValue(firstField);
          }
          else if (firstField == "*")
          {
            if (parserResult.DataCount > 0)
            {
              resultObject[alias] = parserResult.DataValue;
            }
            else
            {
              resultObject[alias] = null;
            }
          }
          else
          {
            resultObject[alias] = parserResult.DataValue;
          }
        }
        else
        {
          resultObject[alias] = parserResult.DataValue;
        }
        totalDataCount += parserResult.DataCount;
        resultIndex++;
      } while (reader.NextResult());

      return resultObject;
    }
  }
}
